﻿'*******************************************************************************************
'* Copyright Brügmann Software GmbH, Papenburg
'* Author: Björn Kremer
'* Contact: codeplex<at>patorg.de
'* 
'* VB.CMIS is a VB.NET implementation of the Content Management Interoperability Services (CMIS) standard
'*
'* This file is part of VB.CMIS.
'* 
'* VB.CMIS is free software: you can redistribute it and/or modify
'* it under the terms of the GNU Lesser General Public License as published by
'* the Free Software Foundation, either version 3 of the License, or
'* (at your option) any later version.
'* 
'* VB.CMIS is distributed in the hope that it will be useful,
'* but WITHOUT ANY WARRANTY; without even the implied warranty of
'* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'* GNU Lesser General Public License for more details.
'* 
'* You should have received a copy of the GNU Lesser General Public License
'* along with VB.CMIS. If not, see <http://www.gnu.org/licenses/>.
'*******************************************************************************************
Imports System.Xml.Serialization

Namespace Properties
   <XmlRoot("cmisProperty", Namespace:=CmisNamespaceConstants.Cmis)>
   Public MustInherit Class CmisProperty(Of ValueType)
      Implements ICMISProperty
      Implements IXmlSerializable


      Public Property PropertyDefinitionId() As String Implements ICMISProperty.PropertyDefinitionId

      Public Property LocalName() As String Implements ICMISProperty.LocalName

      Public Property DisplayName() As String Implements ICMISProperty.DisplayName

      Public Property QueryName() As String Implements ICMISProperty.QueryName

      Public Property Values As ValueType()

      Public Property UntypedValues As Object Implements ICMISProperty.UntypedValues
         Get
            Return Values
         End Get
         Set(value As Object)
            Values = DirectCast(value, ValueType())
         End Set
      End Property


      Public Sub New(propertyDefinitionId As String, localName As String, displayName As String, queryName As String, values As ValueType())
         Me.PropertyDefinitionId = propertyDefinitionId
         Me.LocalName = localName
         Me.DisplayName = displayName
         Me.QueryName = queryName
         Me.Values = values
      End Sub

      Public Sub New()
         MyBase.New()
      End Sub

      Protected Overridable Function GetValueForSerialization() As List(Of String)
         Dim retVal As New List(Of String)
         If Values IsNot Nothing AndAlso (Values.Count > 1 OrElse Values.FirstOrDefault IsNot Nothing) Then
            For Each item As Object In Values
               retVal.Add(CStr(item))
            Next
         End If
         Return retVal
      End Function
      
      Protected Overridable Sub SetSerializedValues(values As List(Of String))
         Dim converter As ComponentModel.TypeConverter = ComponentModel.TypeDescriptor.GetConverter(GetType(ValueType))
         Dim tmpValues As New List(Of ValueType)
         For Each Val As String In values
            Dim tmpVal As ValueType = DirectCast(converter.ConvertFromString(Val), ValueType)
            If tmpVal IsNot Nothing Then
               tmpValues.Add(tmpVal)
            End If
         Next
         Me.Values = tmpValues.ToArray
      End Sub


      Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema
         Return Nothing
      End Function

      Public Sub ReadXml(reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml
         Dim doc As New System.Xml.XmlDocument()
         doc.Load(reader)


         Dim node As System.Xml.XmlNode = Common.GetItemCaseInsensitiveFromXML(doc, Common.GetXMLRootName(Me.GetType).ToLowerInvariant)

         For Each attr As System.Xml.XmlAttribute In node.Attributes
            Dim lName As String = Common.GetNodeNameWithoutPrefix(attr).ToLowerInvariant
            If lName.Equals("propertydefinitionid") Then
               PropertyDefinitionId = attr.InnerText
            ElseIf lName.Equals("localname") Then
               LocalName = attr.InnerText
            ElseIf lName.Equals("displayname") Then
               DisplayName = attr.InnerText
            ElseIf lName.Equals("queryname") Then
               QueryName = attr.InnerText
            End If
         Next

         Dim values As New List(Of String)
         For Each child As System.Xml.XmlNode In node.ChildNodes
            Dim lName As String = Common.GetNodeNameWithoutPrefix(child).ToLowerInvariant
            If lName.Equals("value") Then
               values.Add(child.InnerText)
            End If
         Next
         SetSerializedValues(values)
      End Sub

      Public Sub WriteXml(writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml
         Dim ns As String = CmisNamespaceConstants.Cmis
         If Not String.IsNullOrEmpty(Me.PropertyDefinitionId) Then
            writer.WriteAttributeString("propertyDefinitionId", Me.PropertyDefinitionId)
         End If
         If Not String.IsNullOrEmpty(Me.LocalName) Then
            writer.WriteAttributeString("localName", Me.LocalName)
         End If
         If Not String.IsNullOrEmpty(Me.DisplayName) Then
            writer.WriteAttributeString("displayName", Me.DisplayName)
         End If
         If Not String.IsNullOrEmpty(Me.QueryName) Then
            writer.WriteAttributeString("queryName", Me.QueryName)
         End If
         For Each item As String In GetValueForSerialization()
            writer.WriteElementString("value", ns, item)
         Next

      End Sub
   End Class
End Namespace